<script setup lang="ts">
import { nextTick, ref, unref } from 'vue'
import { getBusinessBind } from '@/utils/custom'
import { getRelName, isShowCol } from '@/views/components/form/libs'
import type { FormInstance } from 'element-plus'
import type { BusinessUIQueryColumnType } from '@/types/custom'

import TemplatePre from '@/views/components/form/components/TemplatePre.vue'
import TemplateJson from '@/views/components/form/components/TemplateJson.vue'
import TemplateAnnex from '@/views/components/form/components/TemplateAnnex.vue'
import TemplateImage from '@/views/components/form/components/TemplateImage.vue'
import TemplateTitle from '@/views/components/form/components/TemplateTitle.vue'
import TemplateBusiness from '@/views/components/form/components/TemplateBusiness.vue'
import TemplateFormContent from '@/views/components/form/components/TemplateFormContent.vue'
import TemplateSelector from '@/views/components/form/components/TemplateSelector.vue'

interface Props {
  items: BusinessUIQueryColumnType[]
  getOptions: (form: BusinessUIQueryColumnType) => SelectOptionType[]
  labelPosition?: string
  can_edit_items?: string[]
  params?: TypedAny
}

const modelValue = defineModel<any>({})

const props = withDefaults(defineProps<Props>(), {
  labelPosition: 'right'
})

const emit = defineEmits(['linkage'])

// 表单
const ruleFormRef = ref<FormInstance>()

const onLinkageChange = (form: BusinessUIQueryColumnType) => {
  emit('linkage', form)
}

/**
 * 获取禁用
 * @param form
 */
const getDisabled = (form: BusinessUIQueryColumnType) => {
  const disable_on_edit = Boolean(form.disable_on_edit && modelValue.value.id)
  if (props.can_edit_items) {
    return disable_on_edit || !props.can_edit_items?.includes(form.field)
  } else {
    return disable_on_edit
  }
}

/**
 * 获取表单label
 * @param form
 */
const getFormLabel = (form: BusinessUIQueryColumnType) => {
  if (
    ![
      'custom-title',
      'el-alert',
      'api-alert',
      'custom-pre',
      'custom-annex',
      'custom-image',
      'custom-json',
      'custom-business-form'
    ].includes(form.component)
  ) {
    return form.title
  } else return ''
}

/**
 * 是否是分组
 * @param form
 */
const getFormRules = (form: BusinessUIQueryColumnType) => {
  if (form.required) {
    return [{ required: true, message: `请输入${form.title}`, trigger: 'change' }]
  } else {
    return []
  }
}

const validate = (callback: (valid: boolean) => void) => {
  ruleFormRef.value?.validate((valid) => {
    callback(valid)
  })
}

const clearValidate = () => {
  nextTick(() => {
    const $form = unref(ruleFormRef)
    if ($form) $form.clearValidate()
  })
}

defineExpose({ validate, clearValidate })
</script>

<template>
  <el-form
    ref="ruleFormRef"
    :model="modelValue"
    label-width="auto"
    :label-position="labelPosition"
    class="template-form"
  >
    <el-row :gutter="10">
      <template v-for="(form, index) in items">
        <el-col
          v-if="isShowCol(form, modelValue)"
          :key="index"
          v-bind="form.set_json_parse.col"
          class="mb5"
        >
          <el-form-item
            :label="getFormLabel(form)"
            :prop="form.field"
            :required="form.required"
            :rules="getFormRules(form)"
          >
            <el-text v-if="['el-text'].includes(form.component)" v-bind="getBusinessBind(form)">
              {{ getRelName(form, {}, modelValue) }}
            </el-text>
            <el-input
              v-else-if="['el-input', 'el-input-textarea'].includes(form.component)"
              :disabled="getDisabled(form)"
              v-bind="getBusinessBind(form)"
              v-model="modelValue[form.field]"
              @change="onLinkageChange(form)"
              class="w100"
            />
            <el-radio-group
              v-else-if="form.elComponent === 'el-radio-group'"
              v-model="modelValue[form.field]"
              :disabled="getDisabled(form)"
              v-bind="getBusinessBind(form)"
              @change="onLinkageChange(form)"
            >
              <el-radio-button
                v-for="item in getOptions(form)"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-radio-group>
            <el-checkbox-group
              v-else-if="form.elComponent === 'el-checkbox-group'"
              v-model="modelValue[form.field]"
              :disabled="getDisabled(form)"
              v-bind="getBusinessBind(form)"
              @change="onLinkageChange(form)"
            >
              <el-checkbox
                v-for="item in getOptions(form)"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-checkbox-group>
            <el-input-number
              v-else-if="['el-input-number'].includes(form.component)"
              :disabled="getDisabled(form)"
              v-bind="getBusinessBind(form)"
              v-model="modelValue[form.field]"
              @change="onLinkageChange(form)"
              class="w100"
            />
            <el-switch
              v-else-if="['el-switch'].includes(form.component)"
              :disabled="getDisabled(form)"
              v-bind="getBusinessBind(form)"
              v-model="modelValue[form.field]"
              @change="onLinkageChange(form)"
            />
            <el-color-picker
              v-else-if="['el-color-picker'].includes(form.component)"
              :disabled="getDisabled(form)"
              v-bind="getBusinessBind(form)"
              v-model="modelValue[form.field]"
              @change="onLinkageChange(form)"
            />
            <el-rate
              v-else-if="['el-rate'].includes(form.component)"
              :disabled="getDisabled(form)"
              v-bind="getBusinessBind(form)"
              v-model="modelValue[form.field]"
              @change="onLinkageChange(form)"
            />
            <el-button
              v-else-if="['el-button'].includes(form.component)"
              :disabled="getDisabled(form)"
              v-bind="getBusinessBind(form)"
              v-model="modelValue[form.field]"
              >{{ form.title || form.field }}
            </el-button>
            <el-slider
              v-else-if="['el-slider'].includes(form.component)"
              :disabled="getDisabled(form)"
              v-bind="getBusinessBind(form)"
              v-model="modelValue[form.field]"
              @change="onLinkageChange(form)"
              >{{ form.title || form.field }}
            </el-slider>
            <el-date-picker
              v-else-if="['el-date-picker'].includes(form.component)"
              :disabled="getDisabled(form)"
              v-bind="getBusinessBind(form)"
              v-model="modelValue[form.field]"
              @change="onLinkageChange(form)"
              class="w100"
            />
            <el-alert
              v-else-if="
                ['el-alert', 'api-alert'].includes(form.component) &&
                (modelValue[form.field] || form.title)
              "
              :description="modelValue[form.field]"
              v-bind="getBusinessBind(form)"
              :title="form.title"
              class="el-alert-pre"
            />
            <el-select
              v-else-if="form.elComponent === 'el-select'"
              :disabled="getDisabled(form)"
              v-bind="getBusinessBind(form)"
              v-model="modelValue[form.field]"
              @change="onLinkageChange(form)"
            >
              <el-option
                v-for="item in getOptions(form)"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
            <el-segmented
              v-else-if="form.elComponent === 'el-segmented'"
              v-model="modelValue[form.field]"
              :options="getOptions(form)"
              v-bind="getBusinessBind(form)"
              @change="onLinkageChange(form)"
            />
            <el-tree-select
              v-else-if="form.elComponent === 'el-tree-select'"
              v-model="modelValue[form.field]"
              :disabled="getDisabled(form)"
              v-bind="getBusinessBind(form)"
              :data="getOptions(form)"
              @change="onLinkageChange(form)"
              class="w100"
            />
            <el-cascader
              v-else-if="form.elComponent === 'el-cascader'"
              v-model="modelValue[form.field]"
              :disabled="getDisabled(form)"
              v-bind="getBusinessBind(form)"
              :data="getOptions(form)"
              @change="onLinkageChange(form)"
              class="w100"
            />
            <TemplateSelector
              v-else-if="form.component === 'custom-selector'"
              v-model="modelValue[form.field]"
              :title="form.title"
              :business_id="form.business_id"
              :field="form.field"
              :disabled="getDisabled(form)"
              v-bind="getBusinessBind(form)"
              @change="onLinkageChange(form)"
              class="w100"
            />
            <TemplateBusiness
              v-else-if="['custom-business'].includes(form.component)"
              v-model="modelValue[form.field]"
              :item="form"
              :form-params="modelValue"
              :disabled="getDisabled(form)"
              class="w100"
            />
            <TemplateFormContent
              v-else-if="['custom-business-form'].includes(form.component)"
              :model-value="form.business_id"
              :item="form"
              :form-id="modelValue[form.field]"
              :params="params"
              :disabled="getDisabled(form)"
              :is-form="false"
              class="w100"
            />
            <TemplateAnnex
              v-else-if="['custom-annex'].includes(form.component)"
              v-model="modelValue[form.field]"
              :title="form.title"
              :disabled="getDisabled(form)"
              v-bind="getBusinessBind(form)"
              @change="onLinkageChange(form)"
              class="w100"
            />
            <TemplateImage
              v-else-if="['custom-image'].includes(form.component)"
              v-model="modelValue[form.field]"
              :title="form.title"
              :disabled="getDisabled(form)"
              v-bind="getBusinessBind(form)"
              @change="onLinkageChange(form)"
              class="w100"
            />
            <TemplatePre
              v-else-if="['custom-pre'].includes(form.component)"
              v-model="modelValue[form.field]"
              :form="form"
              class="color-base"
            />
            <TemplateJson
              v-else-if="['custom-json'].includes(form.component)"
              v-model="modelValue[form.field]"
              :form="form"
            />
            <TemplateTitle
              v-else-if="['custom-title'].includes(form.component)"
              v-model="modelValue[form.field]"
              :form="form"
            />
            <span v-else>暂无 {{ form.component }}</span>
          </el-form-item>
        </el-col>
      </template>
    </el-row>
  </el-form>
</template>
